package net.ericaro.neojavagengen;

import net.ericaro.neojavagen.Literals;
import net.ericaro.neojavagen.classes.InterfaceTypes;
import net.ericaro.neojavagen.names.QualifiedIdentifier;
import net.ericaro.neojavagen.types.ClassOrInterfaceType;
import net.ericaro.neojavagen.types.Identifier;
import net.ericaro.neojavagen.types.InterfaceType;
import net.ericaro.neojavagen.types.TypedIdentifier;




public class MetaType {

	Meta implementation;
	String name;
	Grammar grammar;
	private QualifiedIdentifier qualifiedPackageName;
	private Identifier nameIdentifier;
	private QualifiedIdentifier qualifiedTypeName;
	private InterfaceTypes interfaceTypes;

	public MetaType(Grammar g, String name) {
		super();
		this.name = name;
		this.nameIdentifier = Literals.identifier(name);
		this.grammar = g;
	}
	
	public void attach(Meta impl){
		assert this.implementation == null : "it's a mistake to attach a meta to an already attached metatype";
		this.implementation = impl;
	}
	
	public void setPackageName(Identifier packageName) {
		qualifiedPackageName = new QualifiedIdentifier(Literals.identifier("net"),Literals.identifier("ericaro"),Literals.identifier("neojavagen"), packageName);
	}

	
	public Identifier getNameIdentifier() {
		return nameIdentifier;
	}
	
	public QualifiedIdentifier getQualifiedTypeName() {
		if (qualifiedTypeName == null ) {
			getQualifiedPackageName();
			qualifiedTypeName = new QualifiedIdentifier(qualifiedPackageName.toArray(new Identifier[0]));
			qualifiedTypeName.add(getNameIdentifier());
		}
		return qualifiedTypeName;
	} 
	
	public ClassOrInterfaceType getClassOrInterfaceType(){
		ClassOrInterfaceType typedIdentifiers = new ClassOrInterfaceType();
		for(Identifier  i: getQualifiedTypeName()) 
			typedIdentifiers.add(new TypedIdentifier(i));
		return typedIdentifiers;
	}
	
	
	
	
	public QualifiedIdentifier getQualifiedPackageName(){
		return qualifiedPackageName;
	}

	public InterfaceTypes getInterfaceTypes() {
		if (interfaceTypes == null ) {
			interfaceTypes = new InterfaceTypes();
		}
		return interfaceTypes;
	}
	
	void addInterfaceType(InterfaceType type){
		getInterfaceTypes().add(type);
	}
	
}
